package demo.retry;

import com.github.rholder.retry.Attempt;
import com.github.rholder.retry.RetryException;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategy;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

/**
 * 使用组件进行重试
 */
public class RetryDemo {

    public static void main(String[] args) {
        Integer[] integers = {1, 10, 6, 9};

        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
            .retryIfExceptionOfType(Exception.class)
            //重调策略
            .withWaitStrategy(new CustomTimeWaitStrategy(integers, TimeUnit.SECONDS))
            //尝试次数
            .withStopStrategy(StopStrategies.stopAfterAttempt(integers.length))
            .build();
        try {
            //执行指定的方法。
            retryer.call(() -> {
                System.err.println("do something...");
                throw new Exception("我是一个异常!");
            });
        } catch (ExecutionException | RetryException e) {
            e.printStackTrace();
        }
    }

    public static class CustomTimeWaitStrategy implements WaitStrategy {

        private final Long[] times;

        private final TimeUnit timeUnit;

        public CustomTimeWaitStrategy(Integer[] time, TimeUnit timeUnit) {
            final Long[] ftime = new Long[time.length];
            Stream.iterate(0, n -> n+1).limit(time.length).forEach(v -> {
                ftime[v] = timeUnit.toMillis(time[v]);
            });
            this.times = ftime;
            this.timeUnit = timeUnit;
        }

        @Override
        public long computeSleepTime(Attempt attempt) {
            long attemptNumber = attempt.getAttemptNumber();
            return times[(int) attemptNumber];
        }
    }


}
